package com.xinqi.printByThreadsWithLoop.byReentrantLockForever.august2_01;


import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author xinqi
 * @date 2023/8/2 12:58
 */
@Slf4j(topic = "testXinThread")
public class XinThread {
    public static void main(String[] args) {

        MyTask myTask = new MyTask();
        new Thread(myTask::printOdd).start();
        new Thread(myTask::printEven).start();
        System.out.println();
    }
}
@Slf4j(topic = "testMyTask")
class MyTask{
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition oddWaitSet = lock.newCondition();
    private final Condition evenWaitSet = lock.newCondition();
    int count = 1;
    public void printOdd(){
        while (true){
            lock.lock();
            try {
                oddWaitSet.await(1, TimeUnit.SECONDS);
//                System.out.print(count++);//2023-8-2-15：30为什么不使用System.out.print?因为System.out.print用了synchronized，可能会造成干扰，所以使用slf4j,slf4j就一定可以吗？可以去看看塔的源码
//                2023-8-2-15：40（那么System.out.print到底有没有干扰呢？不好说，需要去查看）
                //2023-8-2-15：41：分析：因为打印时只有一个处于running的线程才会打印，所以说打印的变量和有没有加锁无关，
                //2023-8-2-15：41，经过以上讨论，无论是System.out.print或是slf4j的打印都可以。（如果有误，希望可以练习作者修改）

                log.debug("{}",count++);
                Thread.sleep(1 * 1000);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                evenWaitSet.signal();
                lock.unlock();
            }
        }
    }

    public void printEven() {

        while (true){
            lock.lock();
            try {
                evenWaitSet.await();
//                System.out.print(count++);
                log.debug("{}",count++);

                Thread.sleep(1 * 1000);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                oddWaitSet.signal();
                lock.unlock();
            }
        }
    }
}